﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Extend.Pool
{
    public abstract class UnityObjPoolBase<T> : PoolBase where T: UnityEngine.Object
    {
        /*
         Unity GameObject 和 组件 池父类
             */

        public override int CountUnUsed { get { return _pool.Count; } protected set { return; } }

        protected Stack<T> _pool = new Stack<T>();
        protected T _original;
        protected Transform _parent;

        protected abstract GameObject GetGameobject(T t);

        protected abstract Transform GetTransform(T t);

        protected abstract T GetNewInstance();

        protected void Init(T original, Transform parent = null, int capacity = int.MaxValue)
        {
            Capacity = capacity;
            _original = original;
            _parent = parent ?? PoolContainer.Transform;
        }

        public T Spawn()
        {
            if (_original == null)
            {
                Debug.LogError("池模板已经被销毁，无法创建对象，请重新创建新的池对象");
                return null;
            }
            T result = null;
            if (_pool.Count > 0)
            {
                result = _pool.Pop();
            }
            else
            {
                result = GetNewInstance();
                Count++;
            }
            GetGameobject(result).SetActive(true);
            return result;
        }

        public bool Recycle(T obj)
        {
            if (obj == null)
                return false;
            if (_pool.Count < Capacity)
            {
                GetGameobject(obj).SetActive(false);
                GetTransform(obj).SetParent(_parent);
                _pool.Push(obj);
                return true;
            }
            else
            {
                GameObject.Destroy(GetGameobject(obj));
                Count--;
                return false;
            }
        }

        public override void ReleaseUnused()
        {
            while (_pool.Count > 0)
            {
                GameObject.Destroy(GetGameobject(_pool.Pop()));
            }
        }
    }
}

